home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / RKMLibsPrgs / graphics_libraries / text / cliptext.c < prev    next >
C/C++ Source or Header  |  1992-09-03  |  15KB  |  310 lines

  1. ;/* cliptext.c - Execute me to compile me with Lattice 5.10a
  2. LC -cfistq -v -y -j73 cliptext.c
  3. Blink FROM LIB:c.o,cliptext.o TO cliptext LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit ;*/
  5.  
  6. #include <exec/types.h>
  7. #include <dos/rdargs.h>
  8. #include <dos/dosextens.h>
  9. #include <intuition/intuition.h>
  10. #include <graphics/text.h>
  11. #include <graphics/displayinfo.h>
  12. #include <graphics/regions.h>
  13. #include <graphics/gfx.h>
  14. #include <libraries/diskfont.h>
  15. #include <libraries/diskfonttag.h>
  16. #include <utility/tagitem.h>
  17. #include <clib/exec_protos.h>
  18. #include <clib/dos_protos.h>
  19. #include <clib/layers_protos.h>
  20. #include <clib/alib_stdio_protos.h>
  21. #include <clib/intuition_protos.h>
  22. #include <clib/graphics_protos.h>
  23. #include <clib/diskfont_protos.h>
  24.  
  25. #ifdef LATTICE
  26. int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
  27. int chkabort(void) { return(0); }
  28. #endif
  29.  
  30. UBYTE *vers = "\0$VER: cliptext 37.2";
  31.  
  32. #define BUFSIZE          4096
  33. #define FONT_NAME        0
  34. #define FONT_SIZE        1
  35. #define FILE_NAME        2
  36. #define JAM_MODE         3
  37. #define XASP             4
  38. #define YASP             5
  39. #define NUM_ARGS         6
  40. #define DEFAULTFONTSIZE  11L
  41. #define DEFAULTJAMMODE   0L
  42. #define DEFAULTXASP      0L
  43. #define DEFAULTYASP      0L
  44.  
  45. void MainLoop(void);
  46.  
  47. LONG args[NUM_ARGS];
  48. struct TagItem tagitem[2];
  49. UBYTE buffer[BUFSIZE];
  50. BPTR myfile;
  51. struct Library *DiskfontBase, *IntuitionBase, *LayersBase, *GfxBase;
  52. struct IntuiMessage *mymsg;
  53. struct DrawInfo *mydrawinfo;
  54. struct Window *mywin;
  55. struct RastPort *myrp;
  56. struct TTextAttr myta;
  57. struct TextFont *myfont;
  58. struct Rectangle myrectangle;
  59. struct Region *new_region;
  60.  
  61. void main(int argc, char **argv)
  62. {
  63.   extern struct Library *DOSBase;
  64.   struct RDArgs *myrda;
  65.   struct DisplayInfo mydi;
  66.   ULONG mymodeid;
  67.  
  68.   LONG mydefaultfontsize = DEFAULTFONTSIZE;
  69.   LONG mydefaultJAMMode = DEFAULTJAMMODE;
  70.   LONG mydefaultXASP = 0L;
  71.   LONG mydefaultYASP = 0L;
  72.   args[FONT_NAME] = (LONG)"topaz.font";
  73.   args[FONT_SIZE] = (LONG)&mydefaultfontsize;
  74.   args[FILE_NAME] = (LONG)"s:startup-sequence";
  75.   args[JAM_MODE]  = (LONG)&mydefaultJAMMode;
  76.   args[XASP]      = (LONG)&mydefaultXASP;
  77.   args[YASP]      = (LONG)&mydefaultYASP;
  78.  
  79.   if (DOSBase->lib_Version >35)  /* Run only on 2.0 machines */
  80.   {
  81.            /* dos.library standard command line parsing--See the dos.library Autodoc for details */
  82.     if (myrda = ReadArgs("FontName,FontSize/N,FileName,Jam/N,XASP/N,YASP/N\n", args, NULL))
  83.     {
  84.       if (myfile = Open((UBYTE *)args[FILE_NAME], MODE_OLDFILE) )     /* Open the file to display. */
  85.       {
  86.         if (DiskfontBase = OpenLibrary("diskfont.library", 36L))            /* Open the libraries. */
  87.         {
  88.           if (IntuitionBase = OpenLibrary("intuition.library", 36L))
  89.           {
  90.             if (GfxBase = OpenLibrary("graphics.library", 36L))
  91.             {
  92.               if (LayersBase = OpenLibrary("layers.library", 36L))
  93.               {
  94.                 if (mywin = OpenWindowTags(NULL,                              /* Open that window. */
  95.                        WA_MinWidth,     100,       /* This application wants to hear about three   */
  96.                        WA_MinHeight,    100,       /* things: 1) When the user clicks the window's */
  97.                        WA_SmartRefresh, TRUE,      /* close gadget, 2) when the user starts to     */
  98.                        WA_SizeGadget,   TRUE,      /* resize the window, 3) and when the user has  */
  99.                        WA_CloseGadget,  TRUE,      /* finished resizing the window.                */
  100.                        WA_IDCMP,       IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE | IDCMP_SIZEVERIFY,
  101.                        WA_DragBar,     TRUE,
  102.                        WA_DepthGadget, TRUE,
  103.                        WA_Title,       (ULONG)args[FILE_NAME],
  104.                        TAG_END))
  105.                 {
  106.                   tagitem[0].ti_Tag = OT_DeviceDPI;
  107.  
  108.                   /* see if there is a non-zero value in the XASP or YASP fields. Diskfont.library */
  109.                   /* will get a divide by zero GURU if you give it a zero XDPI or YDPI value.      */
  110.  
  111.                                                      /* if there is a zero value in one of them... */
  112.                   if (  ( (*(ULONG *)args[XASP]) == 0) || ( (*(ULONG *)args[YASP]) == 0)  )
  113.                   {
  114.                                  /* ...use the aspect ratio of the current display as a default... */
  115.                     mymodeid = GetVPModeID(&(mywin->WScreen->ViewPort));
  116.                     if (GetDisplayInfoData( NULL, (UBYTE *)&mydi,
  117.                                             sizeof(struct DisplayInfo), DTAG_DISP, mymodeid))
  118.                     {
  119.                       mydefaultXASP = mydi.Resolution.x;
  120.                       mydefaultYASP = mydi.Resolution.y;
  121.                       printf("XAsp = %ld    YAsp = %ld\n", mydefaultXASP, mydefaultYASP);
  122.                       /* notice that the X and Y get _swapped_ to keep the look of
  123.                          the font glyphs the same using screens with different
  124.                          aspect ratios.
  125.                       */
  126.                       args[YASP]    = (LONG)&mydefaultXASP;
  127.                       args[XASP]    = (LONG)&mydefaultYASP;
  128.                     }
  129.                     else           /* ...unless something is preventing us from getting the        */
  130.                                    /* screens resolution.  In that case, forget about the DPI tag. */
  131.                          tagitem[0].ti_Tag = TAG_END;
  132.                   }
  133.                   /* Here we have to put the X and Y DPI into the OT_DeviceDPI tags data field.    */
  134.                   /* THESE ARE NOT REAL X AND Y DPI VALUES FOR THIS FONT OR THE DISPLAY. They only */
  135.                   /* serve to supply the diskfont.library with values to calculate the aspect      */
  136.                   /* ratio.  The X value gets stored in the upper word of the tag value and the Y  */
  137.                   /* DPI gets stored in the lower word.  Because ReadArgs() stores the _address_   */
  138.                   /* of integers it gets from the command line, you have to dereference the        */
  139.                   /* pointer it puts into the argument array, which results in some ugly casting.  */
  140.                   tagitem[0].ti_Data = (ULONG)( ( (UWORD) *( (ULONG *)args[XASP] ) << 16) |
  141.                                                  ((UWORD) *( (ULONG *)args[YASP]) ) );
  142.                   tagitem[1].ti_Tag = TAG_END;
  143.  
  144.                   myta.tta_Name = (STRPTR)args[FONT_NAME];             /* Set up the TTextAttr     */
  145.                   myta.tta_YSize = *((LONG *)args[FONT_SIZE]);         /* structure to match the   */
  146.                   myta.tta_Style = FSF_TAGGED;                         /* font the user requested. */
  147.                   myta.tta_Flags = 0L;
  148.                   myta.tta_Tags = tagitem;
  149.  
  150.                   if (myfont = OpenDiskFont(&myta))   /* open that font */
  151.                   {
  152.                                                           /* This is for the layers.library         */
  153.                                                           /* clipping region that gets attached to  */
  154.                                                           /* the window.  This prevents the         */
  155.                                                           /* application from unnecessarily         */
  156.                     myrectangle.MinX = mywin->BorderLeft; /* rendering beyond the bounds of the     */
  157.                     myrectangle.MinY = mywin->BorderTop;  /* inner part of the window.  For now,    */
  158.                     myrectangle.MaxX = mywin->Width -     /* you can ignore the layers stuff if you */
  159.                         (mywin->BorderRight + 1);         /* are just interested in learning about  */
  160.                     myrectangle.MaxY = mywin->Height -    /* using text.  For more information on   */
  161.                         (mywin->BorderBottom + 1);        /* clipping regions and layers, see the   */
  162.                                                           /* Layers chapter of this manual.         */
  163.  
  164.                     if (new_region = NewRegion())                              /* more layers stuff */
  165.                     {
  166.                       if (OrRectRegion(new_region, &myrectangle));        /* Even more layers stuff */
  167.                       {
  168.                         InstallClipRegion(mywin->WLayer, new_region);
  169.                                                  /* obtain a pointer to the window's rastport and  */
  170.                         myrp = mywin->RPort;     /* set  up some of the rastport attributes.  This */
  171.                         SetFont(myrp, myfont);   /* example obtains the text pen for the window's  */
  172.                         if (mydrawinfo = GetScreenDrawInfo(mywin->WScreen)) /*        screen using */
  173.                         {                                                   /* GetScreenDrawInfo() */
  174.                           SetAPen(myrp, mydrawinfo->dri_Pens[TEXTPEN]);
  175.                           FreeScreenDrawInfo(mywin->WScreen, mydrawinfo);
  176.                         }
  177.                         SetDrMd(myrp, (BYTE)(*((LONG *)args[JAM_MODE])));
  178.  
  179.                         MainLoop();
  180.                       }
  181.                       DisposeRegion(new_region);
  182.                     }
  183.                     CloseFont(myfont);
  184.                   }
  185.                   CloseWindow(mywin);
  186.                 }
  187.                 CloseLibrary(LayersBase);
  188.               }
  189.               CloseLibrary(GfxBase);
  190.             }
  191.             CloseLibrary(IntuitionBase);
  192.           }
  193.           CloseLibrary(DiskfontBase);
  194.         }
  195.         Close(myfile);
  196.       }
  197.       FreeArgs(myrda);
  198.     }
  199.     else VPrintf("Error parsing arguments\n", NULL);
  200.   }
  201. }
  202.  
  203.  
  204. void MainLoop(void)
  205. {
  206.     LONG count, actual, position;
  207.     BOOL aok = TRUE, waitfornewsize = FALSE;
  208.     struct Task *mytask;
  209.  
  210.     mytask = FindTask(NULL);
  211.     Move(myrp, mywin->BorderLeft + 1, mywin->BorderTop + myfont->tf_YSize + 1);
  212.  
  213.     while (((actual = Read(myfile, buffer, BUFSIZE)) > 0) && aok)   /* While there's something   */
  214.     {                                                               /* to read, fill the buffer. */
  215.         position = 0;
  216.         count = 0;
  217.  
  218.         while (position <= actual)
  219.         {
  220.            if (!(waitfornewsize))
  221.            {
  222.                while ( ((buffer[count] >= myfont->tf_LoChar) &&
  223.                        (buffer[count] <= myfont->tf_HiChar)) && (count <= actual) )
  224.                    count++;
  225.  
  226.                Text(myrp, &(buffer[position]), (count)-position);
  227.  
  228.                while ( ((buffer[count] < myfont->tf_LoChar) ||
  229.                        (buffer[count] > myfont->tf_HiChar)) && (count <= actual) )
  230.                {
  231.                    if (buffer[count] == 0x0A)
  232.                        Move(myrp, mywin->BorderLeft, myrp->cp_y + myfont->tf_YSize + 1);
  233.                    count++;
  234.                }
  235.                position = count;
  236.            }
  237.            else WaitPort(mywin->UserPort);
  238.  
  239.            while (mymsg = (struct IntuiMessage *)GetMsg(mywin->UserPort))
  240.            {
  241.                if (mymsg->Class == IDCMP_CLOSEWINDOW)       /* The user clicked the close gadget */
  242.                {
  243.                    aok = FALSE;
  244.                    position = actual + 1;
  245.                    ReplyMsg((struct Message *)mymsg);
  246.                }                                                       /* The user picked up the */
  247.                else if (mymsg->Class == IDCMP_SIZEVERIFY)              /* window's sizing gadget */
  248.                {
  249.                   /* When the user has picked up the window's sizing gadget when the             */
  250.                   /* IDCMP_SIZEVERIFY flag is set, the application has to reply to this message  */
  251.                   /* to tell Intuition to allow the user to move the sizing gadget and resize    */
  252.                   /* the window.  The reason for using this here is because the user can resize  */
  253.                   /* the window while cliptext.c is rendering text to the window. Cliptext.c has */
  254.                   /* to stop rendering text when it receives an IDCMP_SIZEVERIFY message.        */
  255.                   /*                                                                             */
  256.                   /* if this example had instead asked to hear about IDCMP events that could     */
  257.                   /* take place between SIZEVERIFY and NEWSIZE events (especially INTUITICKS),   */
  258.                   /* it should turn off those events here using ModifyIDCMP().                   */
  259.                   /*                                                                             */
  260.                   /* After we allow the user to resize the window, we cannot write into the      */
  261.                   /* window until the user has finished resizing it because we need the          */
  262.                   /* window's new size to adjust the clipping area.  Specifically, we have       */
  263.                   /* to wait for an IDCMP_NEWSIZE message which Intuition will send when the     */
  264.                   /* user lets go of the resize gadget.  For now, we set the waitfornewsize      */
  265.                   /* flag to stop rendering until we get that NEWSIZE message.                   */
  266.  
  267.                    waitfornewsize = TRUE;
  268.                    WaitBlit();
  269.  
  270.                    ReplyMsg((struct Message *)mymsg);            /* The blitter is done, let the */
  271.                }                                                 /* user resize the window.      */
  272.                else
  273.                {
  274.                    ReplyMsg((struct Message *)mymsg);
  275.                    waitfornewsize = FALSE;
  276.                             /* The user has resized the window, so get the new window dimensions */
  277.                    myrectangle.MinX = mywin->BorderLeft;        /* and readjust the layers       */
  278.                    myrectangle.MinY = mywin->BorderTop;         /* clipping region accordingly.  */
  279.                    myrectangle.MaxX = mywin->Width - (mywin->BorderRight + 1);
  280.                    myrectangle.MaxY = mywin->Height - (mywin->BorderBottom + 1);
  281.                    InstallClipRegion(mywin->WLayer, NULL);
  282.                    ClearRegion(new_region);
  283.                    if (OrRectRegion(new_region, &myrectangle))
  284.                        InstallClipRegion(mywin->WLayer, new_region);
  285.                    else
  286.                    {
  287.                        aok = FALSE;
  288.                        position = actual + 1;
  289.                    }
  290.                }
  291.            }
  292.            if (mytask->tc_SigRecvd & SIGBREAKF_CTRL_C)                /* Check for user break.   */
  293.            {
  294.                aok = FALSE;
  295.                position = actual + 1;
  296.            }
  297.  
  298.            if (myrp->cp_y > (mywin->Height - (mywin->BorderBottom + 2))) /* if we reached the    */
  299.            {                                                /* bottom of the page, clear the     */
  300.                Delay(25);                                   /* rastport and move back to the top */
  301.  
  302.                SetRast(myrp, 0);        /* Set the entire rastport to color zero.  This will not */
  303.                Move(myrp,               /* the window borders because of the layers clipping.    */
  304.                mywin->BorderLeft + 1,
  305.                mywin->BorderTop + myfont->tf_YSize + 1);
  306.             }
  307.         }
  308.     }
  309.     if (actual < 0) VPrintf("Error while reading\n", NULL);
  310. }